#pragma once

#include <iostream>
#include <string>
#include <cstdlib>
#include <cstring>
#include <unistd.h>
#include <sys/wait.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <pthread.h>
#include <signal.h>
#include <signal.h>
#include "Log.hpp"
#include "ThreadPool.hpp"
#include "Task.hpp"
#include "Daemon.hpp"
extern Log lg;

const int defaultfd = -1;
const std::string defaultip = "0.0.0.0";
const int backlog = 10;

enum{
    UsageError = 1,
    SocketError,
    BindError,
    ListenError
};

class TcpServer{
public:
    TcpServer(const uint16_t &port, const std::string &ip = defaultip)
    :listensock_(defaultfd),port_(port),ip_(ip)
    {}

    void InitServer()
    {
        listensock_ = socket(AF_INET,SOCK_STREAM,0);
        if(listensock_ < 0)
        {
            lg(Fatal,"create socket, errno: %d, errstring: %s",errno,strerror(errno));
            exit(SocketError);
        } 
        lg(Info,"create socket success, listensock_: %d,",listensock_);

        int opt = 1;
        //setsockopt//??????????????????????????????????????????????
        struct sockaddr_in local;
        memset(&local,0,sizeof(local));
        local.sin_family = AF_INET;
        local.sin_port = htons(listensock_);
        inet_aton(ip_.c_str(),&(local.sin_addr));

        socklen_t len = sizeof(local);
        if(bind(listensock_,(struct sockaddr*)&local,len) < 0 )
        {
            lg(Fatal,"bind error, errno: %d, errnoing: %s",errno,strerror(errno));
            exit(BindError);
        }
            lg(Info,"bind socket success, listensock_: %d", listensock_);

        if(listen(listensock_,backlog) < 0)
        {
            lg(Fatal,"listen error, errno: %d, errnoing: %s",errno,strerror(errno));
            exit(ListenError);
        }
            lg(Info,"listen socket success, listensock_: %d", listensock_);
    }

    void Start()
    {
        Daemon();
        ThreadPool<Task>::GetInstance()->Start();
        lg(Info,"tcpServer is running...");
        for(;;)
        {
            
        }
    }


    ~TcpServer(){}

private:
    int listensock_;
    uint16_t port_;
    std::string ip_;
};